package com.dyh.quickdemozwei;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;

@Slf4j
public class TestOneThreadMultiSchedule {


    @Setter@Getter@AllArgsConstructor
    class Schedule{
        String name;
        Runnable runnable;
        long period;

        public void run(){
            runnable.run();
        }
    }



    class ManagerThread extends Thread{

        long lastTime;
        long frame = 50;//50ms

        Node[] nodes;

        @Getter@Setter
        class Node{
            Schedule schedule;
            long delay;

            public Node(Schedule schedule) {
                this.schedule = schedule;
                this.delay = schedule.period;
            }

            void resetDelay(){
                this.delay = schedule.period;
            }
        }

        public ManagerThread(Schedule... schedules) {
            nodes = new Node[schedules.length];
            for (int i=0;i<schedules.length;i++){
                nodes[i] = new Node(schedules[i]);
            }

        }


        long getDeltaTime(){
            return System.currentTimeMillis()-lastTime;
        }

        @Override
        public void run() {
            lastTime = System.currentTimeMillis();//第一次执行
            for (;;){
                long now = System.currentTimeMillis();
                //5x
                //log.info("frame start now={} lastTime={} deltaTime={}",now,lastTime,now-lastTime);

                /* 处理队列中的*/
                for (int i=0;i<nodes.length;i++){
                    Node node = nodes[i];
                    if (node==null)
                        continue;
//                    log.info("{} {}",node.delay,getDeltaTime());
                    if ((node.delay-=getDeltaTime())>0)
                        continue;
                    node.resetDelay();

                    node.getSchedule().run();

                }

                /*睡前记录*/
                lastTime = System.currentTimeMillis();

                try {
                    Thread.sleep(frame);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }

        }
    }


    @Test
    public void test(){
        ManagerThread managerThread = new ManagerThread(
                new Schedule("S1 1秒  1",()->log.info("S1"),1000L),
//                new Schedule("S11 一秒  11",()->log.info("S11"),1000L),
                new Schedule("S2 30秒  1",()->log.info("S2"),30000L),
                new Schedule("S3 2秒  1",()->log.info("S3"),2000L),
                new Schedule("S4 4秒  1",()->log.info("S4"),4000L),

                new Schedule("S5 1秒  1",()->log.info("S5"),1000L)

                );
        managerThread.setName("managerThread");

        managerThread.start();

        try {
            managerThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}
